import { createRequire } from "node:module";
import { type Plugin } from "vite";
import * as fs from "fs";
import * as svgrCore from "@svgr/core";

const require = createRequire(import.meta.url);
const resolve = require("resolve"); // 拿到 resolve 同步 API

interface SvgrOptions {
  defaultExport: "url" | "component";
}

// @ts-expect-error -- 忽略
const resolvePromise = (id, opt = {}) => {
  return new Promise((fnResolve, fnReject) => {
    // @ts-expect-error -- 忽略
    const cb = (err, res) => {
      if (err) {
        fnReject();
      }
      fnResolve(res);
    };
    try {
      resolve(id, opt, cb);
    } catch (error) {
      console.log(error);
      fnReject();
    }
  });
};

export default function viteSvgrPlugin(options: SvgrOptions): Plugin {
  const { defaultExport = "component" } = options;

  return {
    name: "vite-plugin-svgr",
    async transform(code, id) {
      if (!id.endsWith(".svg")) {
        return code;
      }
      console.log(code);
      const svgrTransform = svgrCore.transform;
      const viteDir = require.resolve("vite");
      console.log("viteDir:", viteDir);
      const esbuildPackagePath = await resolvePromise("esbuild", {
        basedir: viteDir,
      });
      console.log("esbuildPackagePath:", esbuildPackagePath);
      //   import esbuild from esbuildPackagePath
      if (!esbuildPackagePath) return;
      // @ts-expect-error -- 忽略
      const esbuild = await import(esbuildPackagePath);
      //   const esbuild = require(esbuildPackagePath);
      const svg = await fs.promises.readFile(id, "utf8");
      const svgrResult = await svgrTransform(
        svg,
        {
          icon: true,
          jsxRuntime: "classic",
          plugins: ["@svgr/plugin-jsx"],
        },
        { componentName: "ReactComponent" },
      );
      let componentCode = svgrResult;
      //   console.log("pre componentCode:", componentCode);
      if (defaultExport === "url") {
        componentCode = svgrResult.replace(
          "export default ReactComponent",
          "export { ReactComponent }",
        );
        // console.log("after componentCode:", componentCode);
        // 加上 Vite 默认的 `export default 资源路径`
        componentCode += code;
        console.log("end componentCode:");
        console.log(componentCode);
      }
      const result = await esbuild.transform(componentCode, {
        loader: "jsx",
      });
      console.log("code:");
      console.log(result.code);
      return result.code;
    },
  };
}
